jquery.slimscroll.js ➔ hideBar   A
last analyzed

Complexity

Conditions 4

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 9
dl 0
loc 14
rs 9.95
c 0
b 0
f 0
cc 4
1
/*! Copyright (c) 2011 Piotr Rochala (http://rocha.la)
2
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
3
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
4
 *
5
 * Version: 1.3.6
6
 *
7
 */
8
(function($) {
9
10
  $.fn.extend({
11
    slimScroll: function(options) {
12
13
      var defaults = {
14
15
        // width in pixels of the visible scroll area
16
        width : 'auto',
17
18
        // height in pixels of the visible scroll area
19
        height : '250px',
20
21
        // width in pixels of the scrollbar and rail
22
        size : '7px',
23
24
        // scrollbar color, accepts any hex/color value
25
        color: '#000',
26
27
        // scrollbar position - left/right
28
        position : 'right',
29
30
        // distance in pixels between the side edge and the scrollbar
31
        distance : '1px',
32
33
        // default scroll position on load - top / bottom / $('selector')
34
        start : 'top',
35
36
        // sets scrollbar opacity
37
        opacity : .4,
38
39
        // enables always-on mode for the scrollbar
40
        alwaysVisible : false,
41
42
        // check if we should hide the scrollbar when user is hovering over
43
        disableFadeOut : false,
44
45
        // sets visibility of the rail
46
        railVisible : false,
47
48
        // sets rail color
49
        railColor : '#333',
50
51
        // sets rail opacity
52
        railOpacity : .2,
53
54
        // whether  we should use jQuery UI Draggable to enable bar dragging
55
        railDraggable : true,
56
57
        // defautlt CSS class of the slimscroll rail
58
        railClass : 'slimScrollRail',
59
60
        // defautlt CSS class of the slimscroll bar
61
        barClass : 'slimScrollBar',
62
63
        // defautlt CSS class of the slimscroll wrapper
64
        wrapperClass : 'slimScrollDiv',
65
66
        // check if mousewheel should scroll the window if we reach top/bottom
67
        allowPageScroll : false,
68
69
        // scroll amount applied to each mouse wheel step
70
        wheelStep : 20,
71
72
        // scroll amount applied when user is using gestures
73
        touchScrollStep : 200,
74
75
        // sets border radius
76
        borderRadius: '7px',
77
78
        // sets border radius of the rail
79
        railBorderRadius : '7px'
80
      };
81
82
      var o = $.extend(defaults, options);
83
84
      // do it for every element that matches selector
85
      this.each(function(){
86
87
        var isOverPanel, isOverBar, isDragg, queueHide, touchDif,
88
            barHeight, percentScroll, lastScroll,
89
            divS = '<div></div>',
90
            minBarHeight = 30,
91
            releaseScroll = false;
92
93
        // used in event handlers and for better minification
94
        var me = $(this);
95
96
        // ensure we are not binding it again
97
        if (me.parent().hasClass(o.wrapperClass))
98
        {
99
          // start from last bar position
100
          var offset = me.scrollTop();
101
102
          // find bar and rail
103
          bar = me.closest('.' + o.barClass);
104
          rail = me.closest('.' + o.railClass);
105
106
          getBarHeight();
107
108
          // check if we should scroll existing instance
109
          if ($.isPlainObject(options))
110
          {
111
            // Pass height: auto to an existing slimscroll object to force a resize after contents have changed
112
            if ( 'height' in options && options.height == 'auto' ) {
113
              me.parent().css('height', 'auto');
114
              me.css('height', 'auto');
115
              var height = me.parent().parent().height();
116
              me.parent().css('height', height);
117
              me.css('height', height);
118
            }
119
120
            if ('scrollTo' in options)
121
            {
122
              // jump to a static point
123
              offset = parseInt(o.scrollTo);
124
            }
125
            else if ('scrollBy' in options)
126
            {
127
              // jump by value pixels
128
              offset += parseInt(o.scrollBy);
129
            }
130
            else if ('destroy' in options)
131
            {
132
              // remove slimscroll elements
133
              bar.remove();
134
              rail.remove();
135
              me.unwrap();
136
              return;
137
            }
138
139
            // scroll content by the given offset
140
            scrollContent(offset, false, true);
141
          }
142
143
          return;
144
        }
145
        else if ($.isPlainObject(options))
146
        {
147
          if ('destroy' in options)
148
          {
149
            return;
150
          }
151
        }
152
153
        // optionally set height to the parent's height
154
        o.height = (o.height == 'auto') ? me.parent().height() : o.height;
155
156
        // wrap content
157
        var wrapper = $(divS)
158
            .addClass(o.wrapperClass)
159
            .css({
160
              position: 'relative',
161
              overflow: 'hidden',
162
              width: o.width,
163
              height: o.height
164
            });
165
166
        // update style for the div
167
        me.css({
168
          overflow: 'hidden',
169
          width: o.width,
170
          height: o.height
171
        });
172
173
        // create scrollbar rail
174
        var rail = $(divS)
175
            .addClass(o.railClass)
176
            .css({
177
              width: o.size,
178
              height: '100%',
179
              position: 'absolute',
180
              top: 0,
181
              display: (o.alwaysVisible && o.railVisible) ? 'block' : 'none',
182
              'border-radius': o.railBorderRadius,
183
              background: o.railColor,
184
              opacity: o.railOpacity,
185
              zIndex: 90
186
            });
187
188
        // create scrollbar
189
        var bar = $(divS)
190
            .addClass(o.barClass)
191
            .css({
192
              background: o.color,
193
              width: o.size,
194
              position: 'absolute',
195
              top: 0,
196
              opacity: o.opacity,
197
              display: o.alwaysVisible ? 'block' : 'none',
198
              'border-radius' : o.borderRadius,
199
              BorderRadius: o.borderRadius,
200
              MozBorderRadius: o.borderRadius,
201
              WebkitBorderRadius: o.borderRadius,
202
              zIndex: 99
203
            });
204
205
        // set position
206
        var posCss = (o.position == 'right') ? { right: o.distance } : { left: o.distance };
207
        rail.css(posCss);
208
        bar.css(posCss);
209
210
        // wrap it
211
        me.wrap(wrapper);
212
213
        // append to parent div
214
        me.parent().append(bar);
215
        me.parent().append(rail);
216
217
        // make it draggable and no longer dependent on the jqueryUI
218
        if (o.railDraggable){
219
          bar.bind("mousedown", function(e) {
220
            var $doc = $(document);
221
            isDragg = true;
222
            t = parseFloat(bar.css('top'));
0 ignored issues
show
Bug introduced by
The variable t seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.t.
Loading history...
223
            pageY = e.pageY;
0 ignored issues
show
Bug introduced by
The variable pageY seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.pageY.
Loading history...
224
225
            $doc.bind("mousemove.slimscroll", function(e){
226
              currTop = t + e.pageY - pageY;
0 ignored issues
show
Bug introduced by
The variable currTop seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.currTop.
Loading history...
227
              bar.css('top', currTop);
228
              scrollContent(0, bar.position().top, false);// scroll content
229
            });
230
231
            $doc.bind("mouseup.slimscroll", function(e) {
232
              isDragg = false;hideBar();
233
              $doc.unbind('.slimscroll');
234
            });
235
            return false;
236
          }).bind("selectstart.slimscroll", function(e){
237
            e.stopPropagation();
238
            e.preventDefault();
239
            return false;
240
          });
241
        }
242
243
        // on rail over
244
        rail.hover(function(){
245
          showBar();
246
        }, function(){
247
          hideBar();
248
        });
249
250
        // on bar over
251
        bar.hover(function(){
252
          isOverBar = true;
253
        }, function(){
254
          isOverBar = false;
255
        });
256
257
        // show on parent mouseover
258
        me.hover(function(){
259
          isOverPanel = true;
260
          showBar();
261
          hideBar();
262
        }, function(){
263
          isOverPanel = false;
264
          hideBar();
265
        });
266
267
        // support for mobile
268
        me.bind('touchstart', function(e,b){
269
          if (e.originalEvent.touches.length)
270
          {
271
            // record where touch started
272
            touchDif = e.originalEvent.touches[0].pageY;
273
          }
274
        });
275
276
        me.bind('touchmove', function(e){
277
          // prevent scrolling the page if necessary
278
          if(!releaseScroll)
279
          {
280
            e.originalEvent.preventDefault();
281
          }
282
          if (e.originalEvent.touches.length)
283
          {
284
            // see how far user swiped
285
            var diff = (touchDif - e.originalEvent.touches[0].pageY) / o.touchScrollStep;
286
            // scroll content
287
            scrollContent(diff, true);
288
            touchDif = e.originalEvent.touches[0].pageY;
289
          }
290
        });
291
292
        // set up initial height
293
        getBarHeight();
294
295
        // check start position
296
        if (o.start === 'bottom')
297
        {
298
          // scroll content to bottom
299
          bar.css({ top: me.outerHeight() - bar.outerHeight() });
300
          scrollContent(0, true);
301
        }
302
        else if (o.start !== 'top')
303
        {
304
          // assume jQuery selector
305
          scrollContent($(o.start).position().top, null, true);
306
307
          // make sure bar stays hidden
308
          if (!o.alwaysVisible) { bar.hide(); }
309
        }
310
311
        // attach scroll events
312
        attachWheel(this);
313
314
        function _onWheel(e)
315
        {
316
          // use mouse wheel only when mouse is over
317
          if (!isOverPanel) { return; }
318
319
          var e = e || window.event;
320
321
          var delta = 0;
322
          if (e.wheelDelta) { delta = -e.wheelDelta/120; }
323
          if (e.detail) { delta = e.detail / 3; }
324
325
          var target = e.target || e.srcTarget || e.srcElement;
326
          if ($(target).closest('.' + o.wrapperClass).is(me.parent())) {
327
            // scroll content
328
            scrollContent(delta, true);
329
          }
330
331
          // stop window scroll
332
          if (e.preventDefault && !releaseScroll) { e.preventDefault(); }
333
          if (!releaseScroll) { e.returnValue = false; }
334
        }
335
336
        function scrollContent(y, isWheel, isJump)
337
        {
338
          releaseScroll = false;
339
          var delta = y;
0 ignored issues
show
Unused Code introduced by
The assignment to variable delta seems to be never used. Consider removing it.
Loading history...
340
          var maxTop = me.outerHeight() - bar.outerHeight();
341
342
          if (isWheel)
343
          {
344
            // move bar with mouse wheel
345
            delta = parseInt(bar.css('top')) + y * parseInt(o.wheelStep) / 100 * bar.outerHeight();
346
347
            // move bar, make sure it doesn't go out
348
            delta = Math.min(Math.max(delta, 0), maxTop);
349
350
            // if scrolling down, make sure a fractional change to the
351
            // scroll position isn't rounded away when the scrollbar's CSS is set
352
            // this flooring of delta would happened automatically when
353
            // bar.css is set below, but we floor here for clarity
354
            delta = (y > 0) ? Math.ceil(delta) : Math.floor(delta);
355
356
            // scroll the scrollbar
357
            bar.css({ top: delta + 'px' });
358
          }
359
360
          // calculate actual scroll amount
361
          percentScroll = parseInt(bar.css('top')) / (me.outerHeight() - bar.outerHeight());
362
          delta = percentScroll * (me[0].scrollHeight - me.outerHeight());
363
364
          if (isJump)
365
          {
366
            delta = y;
367
            var offsetTop = delta / me[0].scrollHeight * me.outerHeight();
368
            offsetTop = Math.min(Math.max(offsetTop, 0), maxTop);
369
            bar.css({ top: offsetTop + 'px' });
370
          }
371
372
          // scroll content
373
          me.scrollTop(delta);
374
375
          // fire scrolling event
376
          me.trigger('slimscrolling', ~~delta);
377
378
          // ensure bar is visible
379
          showBar();
380
381
          // trigger hide when scroll is stopped
382
          hideBar();
383
        }
384
385
        function attachWheel(target)
386
        {
387
          if (window.addEventListener)
388
          {
389
            target.addEventListener('DOMMouseScroll', _onWheel, false );
390
            target.addEventListener('mousewheel', _onWheel, false );
391
          }
392
          else
393
          {
394
            document.attachEvent("onmousewheel", _onWheel)
395
          }
396
        }
397
398
        function getBarHeight()
399
        {
400
          // calculate scrollbar height and make sure it is not too small
401
          barHeight = Math.max((me.outerHeight() / me[0].scrollHeight) * me.outerHeight(), minBarHeight);
402
          bar.css({ height: barHeight + 'px' });
403
404
          // hide scrollbar if content is not long enough
405
          var display = barHeight == me.outerHeight() ? 'none' : 'block';
406
          bar.css({ display: display });
407
        }
408
409
        function showBar()
410
        {
411
          // recalculate bar height
412
          getBarHeight();
413
          clearTimeout(queueHide);
414
415
          // when bar reached top or bottom
416
          if (percentScroll == ~~percentScroll)
417
          {
418
            //release wheel
419
            releaseScroll = o.allowPageScroll;
420
421
            // publish approporiate event
422
            if (lastScroll != percentScroll)
423
            {
424
              var msg = (~~percentScroll == 0) ? 'top' : 'bottom';
425
              me.trigger('slimscroll', msg);
426
            }
427
          }
428
          else
429
          {
430
            releaseScroll = false;
431
          }
432
          lastScroll = percentScroll;
433
434
          // show only when required
435
          if(barHeight >= me.outerHeight()) {
436
            //allow window scroll
437
            releaseScroll = true;
438
            return;
439
          }
440
          bar.stop(true,true).fadeIn('fast');
441
          if (o.railVisible) { rail.stop(true,true).fadeIn('fast'); }
442
        }
443
444
        function hideBar()
445
        {
446
          // only hide when options allow it
447
          if (!o.alwaysVisible)
448
          {
449
            queueHide = setTimeout(function(){
450
              if (!(o.disableFadeOut && isOverPanel) && !isOverBar && !isDragg)
451
              {
452
                bar.fadeOut('slow');
453
                rail.fadeOut('slow');
454
              }
455
            }, 1000);
456
          }
457
        }
458
459
      });
460
461
      // maintain chainability
462
      return this;
463
    }
464
  });
465
466
  $.fn.extend({
467
    slimscroll: $.fn.slimScroll
468
  });
469
470
})(jQuery);